<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VNC Client</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #1a1a1a;
            color: #fff;
            font-family: 'Courier New', monospace;
            display: flex;
            flex-direction: column;
            height: 100vh;
        }

        .header {
            background: #2d2d2d;
            padding: 10px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-bottom: 1px solid #444;
        }

        .status {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .status-indicator {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background: #dc3545;
        }

        .status-indicator.connected {
            background: #28a745;
        }

        .status-indicator.connecting {
            background: #ffc107;
            animation: pulse 1s infinite;
        }

        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.5; }
            100% { opacity: 1; }
        }

        .controls {
            display: flex;
            gap: 10px;
        }

        .btn {
            background: #007bff;
            color: white;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
        }

        .btn:hover {
            background: #0056b3;
        }

        .btn:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .btn.disconnect {
            background: #dc3545;
        }

        .btn.disconnect:hover {
            background: #c82333;
        }

        .container {
            flex: 1;
            display: flex;
            flex-direction: column;
            padding: 20px;
            overflow: hidden;
        }

        .connection-form {
            background: #2d2d2d;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }

        .form-group {
            margin-bottom: 15px;
        }

        .form-group label {
            display: block;
            margin-bottom: 5px;
            color: #ccc;
            font-size: 14px;
        }

        .form-group input {
            width: 100%;
            padding: 8px;
            border: 1px solid #444;
            background: #1a1a1a;
            color: #fff;
            border-radius: 4px;
            font-family: 'Courier New', monospace;
        }

        .form-group input:focus {
            outline: none;
            border-color: #007bff;
        }

        .vnc-container {
            flex: 1;
            background: #000;
            border: 1px solid #444;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            overflow: hidden;
        }

        .vnc-screen {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }

        .no-vnc-message {
            text-align: center;
            color: #888;
            font-size: 16px;
        }

        .no-vnc-message h3 {
            color: #ccc;
            margin-bottom: 10px;
        }

        .instructions {
            background: #2d2d2d;
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
            font-size: 14px;
            line-height: 1.6;
        }

        .instructions h4 {
            margin-top: 0;
            color: #ccc;
        }

        .instructions ol {
            margin: 10px 0;
            padding-left: 20px;
        }

        .instructions li {
            margin-bottom: 8px;
        }

        .instructions code {
            background: #1a1a1a;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: 'Courier New', monospace;
            color: #00ff00;
        }

        .error-message {
            background: #dc3545;
            color: white;
            padding: 10px;
            border-radius: 4px;
            margin: 10px 0;
        }

        .success-message {
            background: #28a745;
            color: white;
            padding: 10px;
            border-radius: 4px;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="header">
        <div class="status">
            <div class="status-indicator" id="statusIndicator"></div>
            <span id="statusText">Disconnected</span>
        </div>
        <div class="controls">
            <button id="connectBtn" class="btn">Connect</button>
            <button id="disconnectBtn" class="btn disconnect" disabled>Disconnect</button>
            <button id="fullscreenBtn" class="btn" disabled>Fullscreen</button>
        </div>
    </div>

    <div class="container">
        <div class="connection-form" id="connectionForm">
            <h3>VNC Connection</h3>
            <div class="form-group">
                <label for="host">Host:</label>
                <input type="text" id="host" placeholder="localhost" value="localhost">
            </div>
            <div class="form-group">
                <label for="port">WebSocket Port:</label>
                <input type="number" id="port" placeholder="6900" value="6900">
            </div>
            <div class="form-group">
                <label for="path">Path:</label>
                <input type="text" id="path" placeholder="/api/v1/domains/name/vnc/websocket" value="/websockify">
            </div>
            <div class="form-group">
                <label for="password">Password (optional):</label>
                <input type="password" id="password" placeholder="Leave empty if no password">
            </div>
        </div>

        <div class="vnc-container" id="vncContainer">
            <div class="no-vnc-message" id="noVncMessage">
                <h3>NoVNC WebSocket Proxy</h3>
                <p>Click "Connect" to start the VNC session.</p>
            </div>
            <canvas id="vncCanvas" style="display: none; width: 100%; height: 100%;"></canvas>
        </div>

        <div class="instructions">
            <h4>🔧 Connection Information</h4>
            <p>Based on URL parameters, your connection details are:</p>
            <div id="currentConfig"></div>
        </div>
    </div>

    <script>
        class VNCClient {
            constructor() {
                this.ws = null;
                this.connected = false;
                this.reconnectAttempts = 0;
                this.maxReconnectAttempts = 5;
                this.reconnectDelay = 1000;
                this.canvas = null;
                this.ctx = null;
                this.frameData = [];

                this.initializeUI();
                this.parseURLParams();
                this.initializeCanvas();
            }

            initializeUI() {
                this.statusIndicator = document.getElementById('statusIndicator');
                this.statusText = document.getElementById('statusText');
                this.connectBtn = document.getElementById('connectBtn');
                this.disconnectBtn = document.getElementById('disconnectBtn');
                this.fullscreenBtn = document.getElementById('fullscreenBtn');
                this.vncContainer = document.getElementById('vncContainer');
                this.connectionForm = document.getElementById('connectionForm');
                this.noVncMessage = document.getElementById('noVncMessage');
                this.canvas = document.getElementById('vncCanvas');

                this.connectBtn.addEventListener('click', () => this.connect());
                this.disconnectBtn.addEventListener('click', () => this.disconnect());
                this.fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());
            }

            initializeCanvas() {
                this.ctx = this.canvas.getContext('2d');
            }

            parseURLParams() {
                const urlParams = new URLSearchParams(window.location.search);
                const host = urlParams.get('host') || 'localhost';
                const port = urlParams.get('port') || '6900';
                const path = urlParams.get('path') || '/websockify';
                const password = urlParams.get('password') || '';
                const autoconnect = urlParams.get('autoconnect') === 'true';

                document.getElementById('host').value = host;
                document.getElementById('port').value = port;
                document.getElementById('path').value = path;
                document.getElementById('password').value = password;

                const configDiv = document.getElementById('currentConfig');
                configDiv.innerHTML = `
                    <p><strong>Host:</strong> ${host}</p>
                    <p><strong>Port:</strong> ${port}</p>
                    <p><strong>Path:</strong> ${path}</p>
                    <p><strong>Password:</strong> ${password ? 'Yes (hidden)' : 'No'}</p>
                    <p><strong>Auto-connect:</strong> ${autoconnect ? 'Yes' : 'No'}</p>
                `;

                if (autoconnect) {
                    setTimeout(() => this.connect(), 1000);
                }
            }

            updateStatus(status, message) {
                this.statusText.textContent = message;
                this.statusIndicator.className = `status-indicator ${status}`;

                if (status === 'connected') {
                    this.connectBtn.disabled = true;
                    this.disconnectBtn.disabled = false;
                    this.fullscreenBtn.disabled = false;
                    this.noVncMessage.style.display = 'none';
                    this.canvas.style.display = 'block';
                } else if (status === 'disconnected') {
                    this.connectBtn.disabled = false;
                    this.disconnectBtn.disabled = true;
                    this.fullscreenBtn.disabled = true;
                    this.noVncMessage.style.display = 'block';
                    this.canvas.style.display = 'none';
                } else if (status === 'connecting') {
                    this.connectBtn.disabled = true;
                    this.disconnectBtn.disabled = false;
                    this.fullscreenBtn.disabled = true;
                }
            }

            connect() {
                if (this.connected) return;

                const host = document.getElementById('host').value;
                const port = document.getElementById('port').value;
                const path = document.getElementById('path').value;
                const password = document.getElementById('password').value;

                let wsUrl;
                if (path.startsWith('/')) {
                    wsUrl = `ws://${host}:${port}${path}`;
                } else {
                    wsUrl = `ws://${host}:${port}/${path}`;
                }

                this.updateStatus('connecting', 'Connecting to VNC server...');

                try {
                    this.ws = new WebSocket(wsUrl);
                    this.ws.binaryType = 'arraybuffer';

                    this.ws.onopen = () => {
                        this.connected = true;
                        this.reconnectAttempts = 0;
                        this.updateStatus('connected', 'Connected to VNC server');
                        this.showSuccess('Successfully connected to VNC server');

                        // 发送认证信息（如果需要）
                        if (password) {
                            // VNC密码需要特殊处理，这里简化处理
                            console.log('Password would be sent here if implemented');
                        }
                    };

                    this.ws.onmessage = (event) => {
                        this.handleMessage(event);
                    };

                    this.ws.onclose = () => {
                        this.connected = false;
                        this.updateStatus('disconnected', 'Disconnected from VNC server');
                        this.attemptReconnect();
                    };

                    this.ws.onerror = (error) => {
                        console.error('WebSocket error:', error);
                        this.updateStatus('disconnected', 'Connection error');
                        this.showError('Failed to connect to VNC server.');
                    };

                } catch (error) {
                    console.error('Connection error:', error);
                    this.updateStatus('disconnected', 'Connection failed');
                    this.showError('Failed to establish WebSocket connection.');
                }
            }

            disconnect() {
                if (this.ws) {
                    this.ws.close();
                    this.ws = null;
                }
                this.connected = false;
                this.reconnectAttempts = 0;
                this.updateStatus('disconnected', 'Disconnected');
            }

            handleMessage(event) {
                // 处理VNC协议数据
                if (event.data instanceof ArrayBuffer) {
                    // 处理二进制VNC数据
                    console.log('Received binary VNC data, length:', event.data.byteLength);
                    // 在实际实现中，这里需要解析RFB协议并渲染到canvas
                } else if (typeof event.data === 'string') {
                    // 处理文本消息
                    console.log('Received text message:', event.data);
                }
            }

            attemptReconnect() {
                if (this.reconnectAttempts < this.maxReconnectAttempts) {
                    this.reconnectAttempts++;
                    this.updateStatus('connecting', `Reconnecting... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);

                    setTimeout(() => {
                        this.connect();
                    }, this.reconnectDelay * this.reconnectAttempts);
                } else {
                    this.showError('Max reconnection attempts reached. Please check the server.');
                }
            }

            toggleFullscreen() {
                if (!document.fullscreenElement) {
                    this.vncContainer.requestFullscreen().catch(err => {
                        console.error('Fullscreen error:', err);
                    });
                } else {
                    document.exitFullscreen();
                }
            }

            showSuccess(message) {
                this.showMessage(message, 'success-message');
            }

            showError(message) {
                this.showMessage(message, 'error-message');
            }

            showMessage(message, className) {
                const messageDiv = document.createElement('div');
                messageDiv.className = className;
                messageDiv.textContent = message;

                this.vncContainer.appendChild(messageDiv);

                setTimeout(() => {
                    if (messageDiv.parentNode) {
                        messageDiv.parentNode.removeChild(messageDiv);
                    }
                }, 5000);
            }
        }

        // 初始化VNC客户端
        const vncClient = new VNCClient();
    </script>
</body>
</html>